package com.medusa.aps.business.modules.basic.model.input;

import cn.hutool.core.annotation.Alias;
import com.medusa.aps.business.model.constant.RegexPool;
import com.medusa.aps.business.model.enums.ManufacturingStrategy;
import com.medusa.aps.business.model.enums.ProductionType;
import com.medusa.aps.business.model.enums.SourceEnum;
import com.medusa.aps.business.modules.basic.mp.entity.Material;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.validator.constraints.Length;

import java.math.BigDecimal;

import static com.medusa.aps.business.model.constant.DigitConstants.*;

@Getter
@Setter
@Schema(description = "物料信息")
public class MaterialDTO {

    /**
     * 主键
     */
    @Alias("主键id")
    @Schema(description = "主键")
    private Long id;
    /**
     * 物料编码
     */
    @Alias("物料编码")
    @Schema(description = "物料编码")
    @Length(max = 50, message = "物料编码长度不能超过50")
    @NotBlank(message = "物料编码不能为空")
    @Pattern(regexp = RegexPool.ORDER_NO, message = "物料编码只支持数字、字母、符号")
    private String materialCode;
    /**
     * 物料名称
     */
    @Alias("物料名称")
    @Schema(description = "物料名称")
    @Length(max = 50, message = "物料名称长度不能超过50")
    @NotBlank(message = "物料名称不能为空")
    private String materialName;
    /**
     * 物料分类id
     */
    @Schema(description = "物料分类id")
    @NotNull(message = "物料分类id不能为空")
    private Integer materialClassificationId;

    /**
     * 物料分类
     */
    @Alias("物料分类")
    @Schema(hidden = true)
    private String materialClassificationName;

    /**
     * 生产类型
     */
    @Schema(description = "生产类型")
    @NotNull(message = "生产类型不能为空")
    private ProductionType productionType;


    /**
     * 物料规格
     */
    @Alias("物料规格")
    @Schema(description = "物料规格")
    @Size(max = 50, message = "物料规格长度不能超过50")
    private String materialSpecification;
    /**
     * 制造策略
     */
    @Schema(description = "制造策略")
    @NotNull(message = "制造策略不能为空")
    private ManufacturingStrategy manufacturingStrategy;


    /**
     * 库存
     */
    @Alias("库存")
    @NotNull(message = "库存不能为空")
    @Schema(description = "库存")
    @Digits(integer = 10, fraction = 2, message = "库存最多保留两位小数")
    @DecimalMin(value = "0", message = "库存最小为0")
    @DecimalMax(value = MYSQL_DECIMAL_10_2, message = "库存" + TWELVE_DIGIT_NUMBER_PROMPTS)
    private BigDecimal inventory;

    /**
     * 实际库存
     */
    @Alias("实际库存")
    @Schema(description = "实际库存")
    private BigDecimal actualInventory;
    /**
     * 安全库存
     */
    @Alias("安全库存")
    @Schema(description = "安全库存")
    @NotNull(message = "安全库存不能为空")
    @Digits(integer = 10, fraction = 2, message = "库存最多保留两位小数")
    @DecimalMin(value = "0", message = "安全库存最小为0")
    @DecimalMax(value = MYSQL_DECIMAL_10_2, message = "安全库存" + TWELVE_DIGIT_NUMBER_PROMPTS)
    private BigDecimal safetyInventory;
    /**
     * 最小起订量
     */
    @Alias("最小起订量")
    @Schema(description = "最小起订量")
    private Integer minimumOrderQuantity;
    /**
     * 最大起订量
     */
    @Alias("最大起订量")
    @Schema(description = "最大起订量")
    private Integer maximumOrderQuantity;
    /**
     * 固定提前期
     */
    @Alias("固定提前期")
    @Schema(description = "固定提前期")
    @Min(value = 1, message = "固定提前期最小为1")
    @Max(value = 9999999999L, message = "固定提前期" + TEN_DIGIT_RANGE_PROMPTS)
    private Long fixedLeadTime;
    /**
     * 固定提前期批量
     */
    @Alias("固定提前期批量")
    @Schema(description = "固定提前期批量")
    @Min(value = 1, message = "固定提前期批量最小为1")
    @Max(value = 9999999999L, message = "固定提前期批量" + TEN_DIGIT_RANGE_PROMPTS)
    private Long fixedLeadTimeBatch;
    /**
     * 成品率
     */
    @Alias("成品率")
    @Schema(description = "成品率")
    @Digits(integer = 3, fraction = 2, message = "成品率最多保留两位小数")
    @DecimalMin(value = "1", message = "成品率最小为1")
    @DecimalMax(value = "100", message = "成品率最大为100")
    private BigDecimal finishedProductRate;
    /**
     * 材质
     */
    @Alias("材质")
    @Schema(description = "材质")
    @Size(max = 50, message = "材质最大长度为50")
    private String material;
    /**
     * 数据来源
     */
    @Alias("数据来源")
    @Schema(description = "数据来源")
    private SourceEnum dataSource;
    /**
     * 创建人
     */
    @Alias("创建人")
    @Schema(description = "创建人")
    private String creator;

    /**
     * 物料单位id
     */
    @Alias("物料单位id")
    @Schema(description = "物料单位id")
    @NotNull(message = "物料单位id不能为空")
    private Integer materialUnitId;
    /**
     * 单位
     */
    @Alias("生产单位")
    @Schema(description = "生产单位")
    @NotBlank(message = "生产单位不能为空")
    private String productUnit;
    /**
     * 单位
     */
    @Alias("采购单位")
    @Schema(description = "采购单位")
    private String purchaseUnit;

    /**
     * 单位
     */
//    @Alias("单位")
//    @Schema(description = "单位")
//    @Size(max = 50, message = "单位最大长度为50")
//    private String unit;

    public Material newMaterial() {
        return new Material()
                .setId(id)
                .setMaterialCode(materialCode)
                .setMaterialName(materialName)
                .setMaterialClassificationId(materialClassificationId)
                .setProductionType(productionType)
                .setMaterialSpecification(materialSpecification)
                .setManufacturingStrategy(manufacturingStrategy)
                .setInventory(inventory)
                .setActualInventory(inventory)
                .setSafetyInventory(safetyInventory)
                .setMinimumOrderQuantity(minimumOrderQuantity)
                .setMaximumOrderQuantity(maximumOrderQuantity)
                .setFixedLeadTime(fixedLeadTime)
                .setFixedLeadTimeBatch(fixedLeadTimeBatch)
                .setFinishedProductRate(finishedProductRate)
                .setMaterial(material)
                .setDataSource(SourceEnum.ARTIFICIAL)
                .setMaterialUnitId(materialUnitId)
                .setProductUnit(productUnit)
                .setPurchaseUnit(purchaseUnit);

    }

    public Material updateMaterial(Material pre) {
        BigDecimal result = this.getInventory().subtract(pre.getInventory()).add(pre.getActualInventory());
        result = result.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : result;
        return pre.setMaterialName(materialName)
                .setMaterialClassificationId(materialClassificationId)
                .setProductionType(productionType)
                .setMaterialSpecification(materialSpecification)
                .setManufacturingStrategy(manufacturingStrategy)
                .setInventory(inventory)
                .setActualInventory(result)
                .setSafetyInventory(safetyInventory)
                .setMinimumOrderQuantity(minimumOrderQuantity)
                .setMaximumOrderQuantity(maximumOrderQuantity)
                .setFixedLeadTime(fixedLeadTime)
                .setFixedLeadTimeBatch(fixedLeadTimeBatch)
                .setFinishedProductRate(finishedProductRate)
                .setMaterial(material)
                .setDataSource(SourceEnum.ARTIFICIAL)
                .setMaterialUnitId(materialUnitId)
                .setProductUnit(productUnit)
                .setPurchaseUnit(purchaseUnit);
    }
}
